package com.teamone.mobilewatch.xml;

import java.io.IOException;
import java.io.StringReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;

import com.teamone.mobilewatch.model.PatientReadings;

/**
 * Processes xml string containing list of patients with patient specific data  
 * 
 */
public class PatientReadingsXmlProcessorImpl implements
		XmlProcessor<ArrayList<PatientReadings>> {
	private final static String PATIENT_READINGS_TAG = "PatientReadings";
	private final static String PATIENT_ID_TAG = "PatientId";
	private final static String READINGS_TIME_TAG = "ReadingsTime";
	private final static String BPH_TAG = "BPH";
	private final static String BPL_TAG = "BPL";
	private final static String HR_TAG = "HR";
	private final static String T_TAG = "T";

	private static PatientReadingsXmlProcessorImpl instance;

	private XmlPullParserFactory factory;
	private XmlPullParser xpp;
	private DateFormat formatter; 

	/**
	 * Constructs object
	 * 
	 * @throws XmlPullParserException
	 */
	private PatientReadingsXmlProcessorImpl() throws XmlPullParserException {
		factory = XmlPullParserFactory.newInstance();
		factory.setNamespaceAware(true);
		xpp = factory.newPullParser();
		formatter = new SimpleDateFormat("yyyy-mm-dd'T'hh:mm:ss");
	}

	/**
	 * Returns singleton instance of the class
	 * 
	 * @throws XmlPullParserException
	 */
	public static synchronized PatientReadingsXmlProcessorImpl getInstance()
			throws XmlPullParserException {
		if (null == instance) {
			instance = new PatientReadingsXmlProcessorImpl();
		}
		return instance;
	}

	/**
	 * Processes xml string
	 * 
	 * @return - array list of Patient objects 
	 */
	@Override
	public ArrayList<PatientReadings> process(String xmlString)
			throws IOException, XmlPullParserException, ParseException {
		ArrayList<PatientReadings> patientReadingsRecords = null;
		try {
			xpp.setInput(new StringReader(xmlString));

			int eventType;
			eventType = xpp.getEventType();
			String currentTag = null;
			PatientReadings readings = null;
			patientReadingsRecords = new ArrayList<PatientReadings>();

			while (eventType != XmlPullParser.END_DOCUMENT) {

				// ->ArrayOfPatient\Patient
				if (eventType == XmlPullParser.START_TAG
						&& PATIENT_READINGS_TAG.equals(xpp.getName())) {

					readings = new PatientReadings();
					// iterate through child items of parent element PATIENT_READINGS_TAG
					boolean parentTagEnd = false;
					while (!parentTagEnd) {
						switch (eventType) {
						case XmlPullParser.TEXT:
							String text = xpp.getText();
							if (PATIENT_ID_TAG.equals(currentTag)) {
								readings.setPatientId(Integer.parseInt(text
										.trim()));
							} else if (READINGS_TIME_TAG.equals(currentTag)) {
								readings.setReadingsTime((Date) formatter.parse(text.trim()));
							} else if (BPH_TAG.equals(currentTag)) {
								readings.setBph(Integer.parseInt(text.trim()));
							} else if (BPL_TAG.equals(currentTag)) {
								readings.setBpl(Integer.parseInt(text.trim()));
							} else if (HR_TAG.equals(currentTag)) {
								readings.setHr(Integer.parseInt(text.trim()));
							} else if (T_TAG.equals(currentTag)) {
								readings.setT(Integer.parseInt(text.trim()));
							}
							break;
						case XmlPullParser.START_TAG:
							currentTag = xpp.getName();
							break;
						case XmlPullParser.END_TAG:
							currentTag = null;
							// check if this is the end of the parent tag
							if (PATIENT_READINGS_TAG.equals(xpp.getName())) {
								// completed iteration on child elements - exit
								// loop
								parentTagEnd = true;
							}
							break;
						default:
							break;
						}
						eventType = xpp.next();

					} // end while iteration on Patient
						// append to array list
					patientReadingsRecords.add(readings);
				}

				eventType = xpp.next();
			} // end while

		} catch (IOException e) {
			Log.e("XmlProcessor", e.getMessage());
			throw e;
		} catch (XmlPullParserException e1) {
			Log.e("XmlProcessor", e1.getMessage());
			throw e1;
		}
		return patientReadingsRecords;
	}
}
